package com.yc.cloud.admin.utils;

import com.yc.cloud.admin.dto.request.AlarmRecordUploadReqDTO.DetectionPositionDTO;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 图像处理工具类
 */
public class ImageUtils {


    /**
     * 在图片上绘制检测框
     *
     * @param imageBytes 原始图片字节数组
     * @param detectionPositions 检测位置信息列表
     * @param alarmMessage 告警消息
     * @param isCenter 是否居中显示
     * @return 带有检测框的图片字节数组
     * @throws IOException 如果图片处理过程中发生错误
     */
    public static byte[] drawDetectionBoxes(byte[] imageBytes, List<DetectionPositionDTO> detectionPositions,
                                           String alarmMessage, boolean isCenter) throws IOException {
        return drawDetectionBoxes(imageBytes, detectionPositions, alarmMessage, isCenter, null);
    }

    /**
     * 在图片上绘制检测框（含违规人员姓名）
     *
     * @param imageBytes 原始图片字节数组
     * @param detectionPositions 检测位置信息列表
     * @param alarmMessage 告警消息
     * @param isCenter 是否居中显示
     * @param violatorName 违规人员姓名（可选）
     * @return 带有检测框的图片字节数组
     * @throws IOException 如果图片处理过程中发生错误
     */
    public static byte[] drawDetectionBoxes(byte[] imageBytes, List<DetectionPositionDTO> detectionPositions,
                                           String alarmMessage, boolean isCenter, String violatorName) throws IOException {
        if (detectionPositions == null || detectionPositions.isEmpty()) {
            return imageBytes;
        }

        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageBytes));
        
        // 创建绘图对象
        Graphics2D g2d = originalImage.createGraphics();
        
        // 设置抗锯齿与绘图属性
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(new BasicStroke( Math.max(2, Math.round(0.002f * (originalImage.getWidth() + originalImage.getHeight()) / 2f) + 1 ) ));
        
        // 统一的框颜色和标签文本
        Color boxColor = Color.RED;  // 统一使用红色
        String labelText = alarmMessage != null ? alarmMessage : "告警检测"; // 统一使用告警消息作为标签
        
        // 为每个检测框绘制矩形和标签
        for (DetectionPositionDTO position : detectionPositions) {
            g2d.setColor(boxColor);

            int x = position.getX();
            int y = position.getY();
            int w = position.getWidth();
            int h = position.getHeight();

            // 绘制矩形框
            g2d.drawRect(x, y, w, h);

            // 专业化标签显示：标题、违规人员、置信度
            String alarmText = "告警: " + labelText;
            float confidence = position.getConfidence() == null ? 0f : position.getConfidence();
            String confidenceText = String.format("置信度: %.1f%%", confidence * 100);
            
            // 如果有违规人员姓名，添加到显示内容中
            boolean hasViolator = violatorName != null && !violatorName.trim().isEmpty();
            String violatorText = hasViolator ? "违规人员: " + violatorName : null;

            // 计算动态字号（与C++逻辑等价思路）
            int tl = Math.round(0.002f * (originalImage.getWidth() + originalImage.getHeight()) / 2f) + 1; // 线宽基准
            // 字体粗细近似为线宽-1（AWT无直接tf概念，仅用于计算字号）
            float fontScale = tl / 3.0f;

            // 使用字体缩放模拟（AWT不直接支持scale参数，改用字号近似）
            // 增加基础字体大小，从12调整为18，最小字体从12调整为16
            int fontSize = Math.max(16, Math.round(18 * fontScale));
            Font titleFont = loadChineseFont(fontSize);
            Font violatorFont = loadChineseFont(Math.max(14, fontSize - 1)); // 违规人员字体稍小
            Font confidenceFont = loadChineseFont(Math.max(12, fontSize - 2)); // 置信度字体最小
            
            // 计算文本尺寸
            g2d.setFont(titleFont);
            FontMetrics titleMetrics = g2d.getFontMetrics();
            int titleWidth = titleMetrics.stringWidth(alarmText);
            int titleHeight = titleMetrics.getAscent();
            
            int violatorWidth = 0;
            int violatorHeight = 0;
            if (hasViolator) {
                g2d.setFont(violatorFont);
                FontMetrics violatorMetrics = g2d.getFontMetrics();
                violatorWidth = violatorMetrics.stringWidth(violatorText);
                violatorHeight = violatorMetrics.getAscent();
            }
            
            g2d.setFont(confidenceFont);
            FontMetrics confidenceMetrics = g2d.getFontMetrics();
            int confidenceWidth = confidenceMetrics.stringWidth(confidenceText);
            int confidenceHeight = confidenceMetrics.getAscent();
            
            // 计算标签总尺寸
            int maxWidth = Math.max(titleWidth, Math.max(violatorWidth, confidenceWidth));
            int totalHeight = titleHeight + confidenceHeight + 8; // 8px间距
            if (hasViolator) {
                totalHeight += violatorHeight + 6; // 违规人员文本高度 + 6px间距
            }

            int padding = 8;
            int imgW = originalImage.getWidth();
            int imgH = originalImage.getHeight();

            int bgX, bgY;
            
            if (isCenter) {
                // 居中显示：将标签放在检测框的中心位置
                bgX = x + (w - maxWidth - padding * 2) / 2;
                bgY = y + (h - totalHeight - padding * 2) / 2;
                
                // 确保标签不超出检测框边界
                if (bgX < x) bgX = x;
                if (bgY < y) bgY = y;
                if (bgX + maxWidth + padding * 2 > x + w) {
                    bgX = x + w - maxWidth - padding * 2;
                }
                if (bgY + totalHeight + padding * 2 > y + h) {
                    bgY = y + h - totalHeight - padding * 2;
                }
            } else {
                // 原有逻辑：优先在框的左上角显示（更专业的做法）
                bgX = x;
                bgY = y - totalHeight - padding;
                
                // 如果上方空间不够，显示在框内上方
                if (bgY < 0) {
                    bgY = y + padding;
                }
                
                // 如果框内也放不下，显示在框下方
                if (bgY + totalHeight > y + h - padding) {
                    bgY = y + h + padding;
                    // 如果下方也超出图片，强制显示在框内
                    if (bgY + totalHeight > imgH) {
                        bgY = y + padding;
                    }
                }

                // 保证横向不越界
                if (bgX + maxWidth + padding * 2 > imgW) {
                    bgX = imgW - maxWidth - padding * 2;
                }
                if (bgX < 0) {
                    bgX = 0;
                }
            }

            // 绘制专业化标签背景
            int bgW = maxWidth + padding * 2;
            int bgH = totalHeight + padding * 2;
            
            // 绘制半透明背景
            g2d.setColor(new Color(0, 0, 0, 180)); // 黑色半透明背景
            g2d.fillRoundRect(bgX, bgY, bgW, bgH, 6, 6); // 圆角矩形
            
            // 绘制边框
            g2d.setColor(boxColor);
            g2d.setStroke(new BasicStroke(2));
            g2d.drawRoundRect(bgX, bgY, bgW, bgH, 6, 6);

            // 统一使用白色文字
            g2d.setColor(Color.WHITE);
            
            // 绘制报警文本（主标题）
            g2d.setFont(titleFont);
            int titleX = bgX + padding;
            int titleY = bgY + padding + titleHeight;
            g2d.drawString(alarmText, titleX, titleY);
            
            int currentY = titleY;
            
            // 绘制违规人员（如果有）
            if (hasViolator) {
                g2d.setFont(violatorFont);
                int violatorX = bgX + padding;
                int violatorY = currentY + 6 + violatorHeight; // 6px间距
                g2d.drawString(violatorText, violatorX, violatorY);
                currentY = violatorY;
            }
            
            // 绘制置信度
            g2d.setFont(confidenceFont);
            int confidenceX = bgX + padding;
            int confidenceY = currentY + 8 + confidenceHeight; // 8px间距
            g2d.drawString(confidenceText, confidenceX, confidenceY);
        }
        
        // 释放资源
        g2d.dispose();
        
        // 将处理后的图片转换为字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(originalImage, "jpg", outputStream);
        return outputStream.toByteArray();
    }

    /**
     * 生成缩略图
     * 
     * @param originalImagePath 原图路径
     * @param thumbnailPath 缩略图输出路径
     * @param width 缩略图宽度
     * @param height 缩略图高度
     * @return 是否生成成功
     */
    public static boolean generateThumbnail(String originalImagePath, String thumbnailPath, int width, int height) {
        return generateThumbnail(originalImagePath, thumbnailPath, width, height, 0.8f);
    }
    
    /**
     * 生成缩略图（指定质量）
     * 
     * @param originalImagePath 原图路径
     * @param thumbnailPath 缩略图输出路径
     * @param width 缩略图宽度
     * @param height 缩略图高度
     * @param quality 图片质量 (0.0-1.0)
     * @return 是否生成成功
     */
    public static boolean generateThumbnail(String originalImagePath, String thumbnailPath, int width, int height, float quality) {
        try {
            // 读取原图
            BufferedImage originalImage = ImageIO.read(new java.io.File(originalImagePath));
            if (originalImage == null) {
                System.err.println("无法读取原图: " + originalImagePath);
                return false;
            }
            
            // 计算缩略图尺寸，保持宽高比
            int originalWidth = originalImage.getWidth();
            int originalHeight = originalImage.getHeight();
            
            // 计算缩放比例，保持宽高比
            double scaleX = (double) width / originalWidth;
            double scaleY = (double) height / originalHeight;
            double scale = Math.min(scaleX, scaleY);
            
            int scaledWidth = (int) (originalWidth * scale);
            int scaledHeight = (int) (originalHeight * scale);
            
            // 创建缩略图
            BufferedImage thumbnailImage = new BufferedImage(
                scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
            
            Graphics2D g2d = thumbnailImage.createGraphics();
            
            // 设置高质量渲染参数
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
                               RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, 
                               RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                               RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, 
                               RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            
            // 绘制缩放后的图片
            g2d.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
            g2d.dispose();
            
            // 确保输出目录存在
            java.io.File outputFile = new java.io.File(thumbnailPath);
            java.io.File outputDir = outputFile.getParentFile();
            if (outputDir != null && !outputDir.exists()) {
                outputDir.mkdirs();
            }
            
            // 保存缩略图
            boolean success = ImageIO.write(thumbnailImage, "jpg", outputFile);
            if (success) {
                System.out.println("缩略图生成成功: " + originalImagePath + " -> " + thumbnailPath + 
                                 ", 尺寸: " + scaledWidth + "x" + scaledHeight);
            }
            return success;
            
        } catch (Exception e) {
            System.err.println("生成缩略图异常: " + originalImagePath + ", 错误: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 生成缩略图（从字节数组）
     * 
     * @param imageBytes 原图字节数组
     * @param width 缩略图宽度
     * @param height 缩略图高度
     * @return 缩略图字节数组，失败返回null
     */
    public static byte[] generateThumbnail(byte[] imageBytes, int width, int height) {
        return generateThumbnail(imageBytes, width, height, 0.8f);
    }
    
    /**
     * 生成缩略图（从字节数组，指定质量）
     * 
     * @param imageBytes 原图字节数组
     * @param width 缩略图宽度
     * @param height 缩略图高度
     * @param quality 图片质量 (0.0-1.0)
     * @return 缩略图字节数组，失败返回null
     */
    public static byte[] generateThumbnail(byte[] imageBytes, int width, int height, float quality) {
        try {
            // 读取原图
            BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(imageBytes));
            if (originalImage == null) {
                System.err.println("无法读取图片字节数组");
                return null;
            }
            
            // 计算缩略图尺寸，保持宽高比
            int originalWidth = originalImage.getWidth();
            int originalHeight = originalImage.getHeight();
            
            // 计算缩放比例，保持宽高比
            double scaleX = (double) width / originalWidth;
            double scaleY = (double) height / originalHeight;
            double scale = Math.min(scaleX, scaleY);
            
            int scaledWidth = (int) (originalWidth * scale);
            int scaledHeight = (int) (originalHeight * scale);
            
            // 创建缩略图
            BufferedImage thumbnailImage = new BufferedImage(
                scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
            
            Graphics2D g2d = thumbnailImage.createGraphics();
            
            // 设置高质量渲染参数
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
                               RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, 
                               RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
                               RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, 
                               RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            
            // 绘制缩放后的图片
            g2d.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
            g2d.dispose();
            
            // 转换为字节数组
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(thumbnailImage, "jpg", outputStream);
            return outputStream.toByteArray();
            
        } catch (Exception e) {
            System.err.println("生成缩略图异常: " + e.getMessage());
            return null;
        }
    }

    /**
     * 加载支持中文的字体
     * 优先从项目资源中加载字体文件，如果不存在则使用系统字体
     * 
     * @param fontSize 字体大小
     * @return 字体对象
     */
    private static Font loadChineseFont(int fontSize) {
        try {
            // 优先使用已放置的微软雅黑字体文件
            InputStream fontStream = ImageUtils.class.getResourceAsStream("/fonts/msyh.ttc");
            if (fontStream != null) {
                Font baseFont = Font.createFont(Font.TRUETYPE_FONT, fontStream);
                fontStream.close();
                return baseFont.deriveFont(Font.BOLD, (float) fontSize);
            }
        } catch (Exception e) {
            System.err.println("加载自定义字体失败，使用系统字体: " + e.getMessage());
        }
        
        // 如果自定义字体加载失败，尝试使用系统中文字体
        String[] chineseFonts = {"Microsoft YaHei", "SimHei", "宋体", "黑体"};
        for (String fontName : chineseFonts) {
            Font font = new Font(fontName, Font.BOLD, fontSize);
            if (font.getFamily().equals(fontName)) {
                return font;
            }
        }
        
        // 最后使用系统默认字体
        return new Font(Font.SANS_SERIF, Font.BOLD, fontSize);
    }
    
} 